package com.game.centerserver.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import java.io.InputStream;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.web.multipart.MultipartFile;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.util.EntityUtils;


public class BaseUtil {

    /**
     * 加载配置文件
     * @param filePath
     * @return
     */
    public static Properties loadConfig(String filePath) {
        Properties properties = new Properties();

        try (FileInputStream input = new FileInputStream(filePath)) {
            properties.load(input);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("load config fail.");
        }

        return properties;
    }

    /**
     * 获取文件夹下所有的子目录名
     * @param dir
     * @return
     */
    public static List<Path> getAllSubPathName(Path dir)
    {
        ArrayList<Path> res = new ArrayList<>();

        try {
            // 使用 DirectoryStream 过滤出子目录
            try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
                for (Path entry : stream) {
                    if (Files.isDirectory(entry)) {
                        res.add(entry);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("no dir: " + dir.toString());
        }

        return res;
    }

    /**
     * 递归删除目录及其内容
     * @param directory
     * @return
     */
    public static boolean deleteDirectory(File directory) {
        // 如果目录不存在，返回 false
        if (!directory.exists()) {
            return false;
        }

        // 获取目录中的文件和子目录
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                // 递归删除文件和子目录
                if (file.isDirectory()) {
                    deleteDirectory(file);
                } else {
                    file.delete(); // 删除文件
                }
            }
        }

        // 删除空目录
        return directory.delete();
    }

    /**
     * 验证是否是一个有效的存档
     * @param str
     * @return
     */
    public static boolean isValidArchive(String str) {
        // 正则表达式：一个字母，后跟一个@符号，后跟一个数字
        String regex = "[a-zA-Z]+@[0-9]+";
        boolean res = str.matches(regex);
        return res;
    }

    /**
     * 从文件中获取命令
     * @param filePath
     * @return List<String>
     */
    public static List<String> getcmds(String filePath)
    {
        List<String> lines = new ArrayList<>();
        try {
            lines = Files.readAllLines(Paths.get(filePath));

        } catch (IOException e) {
            e.printStackTrace();
        }
        return lines;
    }

    /**
     * 将字节数组写入文件，并返回对应的File对象。
     *
     * @param bytes 字节数组
     * @param filePath 文件路径（可以是绝对路径或相对路径）
     * @return File 对象
     * @throws IOException 如果写入过程中出现IO错误
     */
    public static File writeByteArrayToFile(byte[] bytes, String filePath) throws IOException {
        // 创建文件
        File file = new File(filePath);
        // 确保父目录存在
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }

        try (FileOutputStream fos = new FileOutputStream(file)) {
            fos.write(bytes);
            fos.flush(); // 确保所有字节都被写入文件
        }

        return file;
    }

    public static byte[] convertFileToByteArray(File file) throws IOException {
        try (FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                bos.write(buffer, 0, bytesRead);
            }
            return bos.toByteArray();
        }
    }

    public static List<String> uploadFile(String targetUrl, File file) throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(targetUrl);

            // 使用MultipartEntityBuilder构建上传请求
            FileBody fileBody = new FileBody(file);
            HttpEntity entity = MultipartEntityBuilder.create()
                    .addPart("file", fileBody)
                    .build();

            httpPost.setEntity(entity);

            // 执行请求
            HttpResponse response = httpClient.execute(httpPost);
            // 获取HTTP响应码
            int statusCode = response.getStatusLine().getStatusCode();
            System.out.println("Response Code: " + statusCode);

            // 读取并打印响应内容（可选）
            String responseBody = EntityUtils.toString(response.getEntity());
            System.out.println("Response Body: " + responseBody);

            System.out.println("Response: " + response);

            ArrayList<String> res = new ArrayList<>();
            res.add(String.valueOf(statusCode));
            res.add(responseBody);

            return res;
        }
    }

    /**
     * 验证文件是否完整
     * @param archivefile
     * @param code
     * @return
     */
    public static boolean archVolatile(File archivefile, String code)
    {
        return false;
    }

    /**
     * 将文件夹directory压缩为tarGzFile
     * @param directory
     * @param tarGzFile
     */
    public static void compressDirectoryToTarGz(File directory,File tarGzFile) {
        try (FileOutputStream fos = new FileOutputStream(tarGzFile);
             GzipCompressorOutputStream gzos = new GzipCompressorOutputStream(fos);
             TarArchiveOutputStream tarOut = new TarArchiveOutputStream(gzos)) {
            tarOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
            addFilesToTar(tarOut, directory,"");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void addFilesToTar(TarArchiveOutputStream tarOut, File file, String base) throws IOException {
        String entryName = base + file.getName();

        if (file.isDirectory()) {
            // 添加目录条目
            TarArchiveEntry entry = new TarArchiveEntry(file, entryName + "/");
            tarOut.putArchiveEntry(entry);
            tarOut.closeArchiveEntry();

            // 递归添加子文件
            for (File child : file.listFiles()) {
                addFilesToTar(tarOut, child, entryName + "/");
            }
        } else {
            // 添加文件条目
            TarArchiveEntry entry = new TarArchiveEntry(file, entryName);
            tarOut.putArchiveEntry(entry);
            try (FileInputStream fis = new FileInputStream(file)) {
                byte[] buffer = new byte[1024];
                int len;
                while ((len = fis.read(buffer)) != -1) {
                    tarOut.write(buffer, 0, len);
                }
            }
            tarOut.closeArchiveEntry();
        }
    }

    /**
     * 解压.tar.gz文件
     * @param tarGzFile
     * @param outputDir
     * @throws IOException
     */
    public static void extractTarGz(File tarGzFile, File outputDir) {
        // 创建输出目录
        if (!outputDir.exists()) {
            outputDir.mkdirs();
        }

        try (InputStream fileInputStream = new FileInputStream(tarGzFile);
             GzipCompressorInputStream gzipInputStream = new GzipCompressorInputStream(fileInputStream);
             TarArchiveInputStream tarInputStream = new TarArchiveInputStream(gzipInputStream)) {

            TarArchiveEntry entry;
            while ((entry = tarInputStream.getNextTarEntry()) != null) {
                File outputFile = new File(outputDir, entry.getName());

                if (entry.isDirectory()) {
                    // 如果是目录，则创建目录
                    outputFile.mkdirs();
                } else {
                    // 如果是文件，则解压文件
                    try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
                        byte[] buffer = new byte[1024];
                        int length;
                        while ((length = tarInputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, length);
                        }
                    }
                }
            }
        }catch ( IOException e){
            e.printStackTrace();
        }
    }

    public static boolean unzip(Path zipfile, Path unziptopath)
    {
        return false;
    }
}


